using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
using System.Resources;
using System.Reflection;
using System.IO;

namespace WinSAG
{
    class WSU_ProcessResults
    {
        //const string xslStringName = @"XSL_Data";
        string resultsFileName;
        string results;
        XmlReader xr;
        object resultsDocument;

        /// <summary>
        /// Initializes a new instance of the <see cref="WSU_ProcessResults"/> class.
        /// </summary>
        /// <param name="resultsFile">The results file.</param>
        internal WSU_ProcessResults(string resultsFile, string styleSheetFileName)
        {
            resultsFileName = resultsFile;
            Stream s = null;
            
            Assembly a = Assembly.GetAssembly(this.GetType());

            // Open the stylesheet if it is a valid file else use the internal 
            // default stylesheet
            if (File.Exists(styleSheetFileName) == true)
            {
                s = File.Open(styleSheetFileName, FileMode.Open);
            }
            else
            {
                s = a.GetManifestResourceStream("WinSAG.simian.xsl");                
            }
            
            // If FileOpen had failed, resort to the internal template
            if (s == null)
            {
                s = a.GetManifestResourceStream("WinSAG.simian.xsl");
            }

            // If we still dont have a valid stream, time to panic. (TODO: Do we have to?)
            if (s == null)
                throw new ApplicationException(WSU_Literals.MSG_EXCEPTION_STYLESHEET_ERROR);

            if (s != null)
            {                
                xr = XmlReader.Create(s);              
            }
        }

        /// <summary>
        /// Gets the results.
        /// </summary>
        /// <returns></returns>
        internal string getResults()
        {
            return results;
        }

        /// <summary>
        /// Sets the results document.
        /// </summary>
        /// <value>The results document.</value>
        public object ResultsDocument
        {
            set { resultsDocument = value; }
        }

        /// <summary>
        /// Computes the result & saves it in a string.
        /// </summary>
        internal void processResults()
        {            
            saveResults(
                doTransformation()
                );
        }

        /// <summary>
        /// Saves the results in to the specified file. 
        /// This function has to be called *only* after processResults() as 
        /// the results are computed only in that function. 
        /// </summary>
        /// <param name="filename">Name of the file to save the results</param>
        internal void saveResultsToFile(string filename)
        {
            try
            {
                File.WriteAllText(filename, results, Encoding.UTF32);                
            }
            catch(Exception e1)
            {
                System.Windows.Forms.MessageBox.Show(String.Format("{0} \n{1}", e1.ToString(), e1.Message), "Exception");
            }
        }

        /// <summary>
        /// Stores the passed value in an internal variable.
        /// </summary>
        /// <param name="results">The results.</param>
        internal void saveResults(string results)
        {            
            try
            {
                this.results = results;
            }
            catch (Exception e1)
            {
                System.Windows.Forms.MessageBox.Show(string.Format("{0} \n{1}", e1.Message, e1.ToString()), "Exception");
            }
        }

        /// <summary>
        /// Does the transformation using the XSL.
        /// </summary>
        /// <returns>Generated result (transformed input)</returns>
        internal string doTransformation()
        {
            XslCompiledTransform xt;
            try
            {
                XPathDocument xd = new XPathDocument(resultsFileName);
                xt = new XslCompiledTransform();
                xt.Load(xr);

                System.IO.StringWriter stWrite = new System.IO.StringWriter();
                xt.Transform(xd, null, stWrite);

                return stWrite.ToString();
            }
            catch (Exception e1)
            {
                return string.Format("<html><body><h1>Error occured:</h1><p>{0}><br/>{1}</p></body></html>", 
                    e1.Message, e1.ToString()
                    );
            }
        }
    }
}